package api

import (
	"fmt"
	"github.com/jinzhu/copier"
	"github.com/labstack/echo/v4"
	"github.com/spf13/cast"
	"longmen/server/pkg/common/api_models"
	"longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/db/mysql/models/models_main"
	cache2 "longmen/server/pkg/db/redis/cache"
	"longmen/server/pkg/grpc_client"
	pb "longmen/server/pkg/protobuf"
)

// @Summary 主播详情页-获取主播的群聊
// @Description 主播详情页-获取主播的群聊
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.GetAnchorProfileReq true "body"
// @Success 200 {object} api_models.GetAnchorProfileResp "result"
// @Router /api/groupChat/getAnchorProfile [POST]
func (base *Controller) GetAnchorProfile(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.GetAnchorProfileReq{}
	if err = util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcTencentImClient.GetAnchorProfile(ctx, &pb.GetAnchorProfileReq{
		AnchorId: uint32(req.AnchorId),
		UserId:   uint64(user.Id),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	res := api_models.GetAnchorProfileResp{}
	copier.Copy(&res, &resp)
	return util.BuildSuccess(c, res, "")
}

// @Summary 聊天页面-删除消息
// @Description 聊天页面-删除消息
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.DelMsgReq true "body"
// @Success 200 {object} api_models.Response "result"
// @Router /api/groupChat/delMsg [POST]
func (base *Controller) DelMsg(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.DelMsgReq{}
	if err = util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err = grpc_client.GrpcTencentImClient.FrontendDelMsg(ctx, &pb.FrontendDelMsgReq{
		GroupId: uint32(req.GroupId),
		UserId:  uint64(user.Id),
		MsgId:   cast.ToString(req.MsgId),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	return util.BuildSuccess(c, nil, "")
}

// @Summary 聊天页面-撤回消息
// @Description 聊天页面-撤回消息
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.RevokeMsgReq true "body"
// @Success 200 {object} api_models.Response "result"
// @Router /api/groupChat/revokeMsg [POST]
func (base *Controller) RevokeMsg(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.RevokeMsgReq{}
	if err = util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err = grpc_client.GrpcTencentImClient.FrontendRevokeMsg(ctx, &pb.FrontendRevokeMsgReq{
		GroupId: uint32(req.GroupId),
		UserId:  uint64(user.Id),
		MsgId:   cast.ToString(req.MsgId),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	return util.BuildSuccess(c, nil, "")
}

// @Summary 聊天页面-禁言用户
// @Description 聊天页面-禁言用户
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.FrontendBanUserReq true "body"
// @Success 200 {object} api_models.Response "result"
// @Router /api/groupChat/banUser [POST]
func (base *Controller) BanUser(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.FrontendBanUserReq{}
	if err = util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err = grpc_client.GrpcTencentImClient.FrontendBanUser(ctx, &pb.FrontendBanUserReq{
		OperateUserId: uint32(user.Id),
		BanUserId:     uint64(req.BanUserId),
		Duration:      uint32(req.Duration),
		Reason:        req.Reason,
		FansGroupId:   req.FansGroupId,
		BanType:       uint32(req.BanType),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	return util.BuildSuccess(c, nil, "")
}

// @Summary 聊天页面-踢出群聊
// @Description 聊天页面-踢出群聊
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.KickUserReq true "body"
// @Success 200 {object} api_models.Response "result"
// @Router /api/groupChat/kickUser [POST]
func (base *Controller) KickUser(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.KickUserReq{}
	if err = util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err = grpc_client.GrpcTencentImClient.FrontendKickUser(ctx, &pb.FrontendKickUserReq{
		OperateUserId: uint32(user.Id),
		KickUserIds:   req.KickUserIds,
		GroupId:       uint32(req.GroupId),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	return util.BuildSuccess(c, nil, "")
}

// @Summary 群聊信息
// @Description 群聊信息
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.GetGroupInfoReq true "body"
// @Success 200 {object} api_models.GetGroupInfoResp "result"
// @Router /api/groupChat/getGroupInfo [POST]
func (base *Controller) GetGroupInfo(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		user = &models_main.User{Id: util.HashUid(base.GetDeviceInfo(c))}
		if user.Id <= 0 {
			return util.BuildLoginTimeOut(c, err)
		}
	}
	req := &api_models.GetGroupInfoReq{}
	if err := util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcTencentImClient.GetGroupInfo(ctx, &pb.GetGroupInfoReq{
		GroupId: uint32(req.GroupId),
		UserId:  uint64(user.Id),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	res := api_models.GetGroupInfoResp{}
	copier.Copy(&res, &resp)
	return util.BuildSuccess(c, res, "")
}

// @Summary 群成员信息
// @Description 群成员信息
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.GetGroupMembersReq true "body"
// @Success 200 {object} api_models.GetGroupMembersResp "result"
// @Router /api/groupChat/getGroupMembers [POST]
func (base *Controller) GetGroupMembers(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		user = &models_main.User{Id: util.HashUid(base.GetDeviceInfo(c))}
		if user.Id <= 0 {
			return util.BuildLoginTimeOut(c, err)
		}
	}
	req := &api_models.GetGroupMembersReq{}
	if err := util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcTencentImClient.GetGroupMembers(ctx, &pb.GetGroupMembersReq{
		GroupId: uint32(req.GroupId),
		UserId:  uint64(user.Id),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	res := api_models.GetGroupMembersResp{}
	copier.Copy(&res, &resp)
	return util.BuildSuccess(c, res, "")
}

// @Summary 清空聊天记录
// @Description 清空聊天记录
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.ClearHistoryReq true "body"
// @Success 200 {object} api_models.Response "result"
// @Router /api/groupChat/clearHistory [POST]
func (base *Controller) ClearHistory(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.ClearHistoryReq{}
	if err := util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err = grpc_client.GrpcTencentImClient.ClearHistory(ctx, &pb.ClearHistoryReq{
		GroupId: uint32(req.GroupId),
		UserId:  uint64(user.Id),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	return util.BuildSuccess(c, nil, "")
}

// @Summary 清空聊天记录并退出群聊
// @Description 清空聊天记录并退出群聊
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.ClearAndQuitReq true "body"
// @Success 200 {object} api_models.Response "result"
// @Router /api/groupChat/clearAndQuit [POST]
func (base *Controller) ClearAndQuit(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.ClearAndQuitReq{}
	if err := util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err = grpc_client.GrpcTencentImClient.ClearAndQuit(ctx, &pb.ClearAndQuitReq{
		GroupId: uint32(req.GroupId),
		UserId:  uint64(user.Id),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	return util.BuildSuccess(c, nil, "")
}

// @Summary 加入群聊
// @Description 加入群聊
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.AddToGroupChatReq true "body"
// @Success 200 {object} api_models.Response "result"
// @Router /api/groupChat/addToGroupChat [POST]
func (base *Controller) AddToGroupChat(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.AddToGroupChatReq{}
	if err := util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err = grpc_client.GrpcTencentImClient.AddToGroupChat(ctx, &pb.AddToGroupChatReq{
		GroupId: uint32(req.GroupId),
		UserId:  uint64(user.Id),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	return util.BuildSuccess(c, nil, "")
}

// @Summary 聊天列表
// @Description 聊天列表
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.GetChatListReq true "body"
// @Success 200 {object} api_models.GetChatListResp "result"
// @Router /api/groupChat/getChatList [POST]
func (base *Controller) GetChatList(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		user = &models_main.User{Id: util.HashUid(base.GetDeviceInfo(c))}
		if user.Id <= 0 {
			return util.BuildLoginTimeOut(c, err)
		}
	}

	req := &api_models.GetChatListReq{}
	if err := util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()

	//暂时去掉群聊
	//groupList, err := grpc_client.GrpcTencentImClient.GetGroupList(ctx, &pb.GetGroupListReq{
	//	UserId: uint64(user.Id),
	//})
	//if err != nil {
	//	return util.BuildFail(c, 1, err.Error(), err)
	//}
	//global.Log.Debugf("请求:%v，GetPrivateChatRecord", user.Id)
	privateChatList, err := grpc_client.GrpcTencentImClient.GetPrivateChatRecord(ctx, &pb.PrivateChatRecordReq{
		UserId:   uint64(user.Id),
		Duration: 15,
		DeviceId: base.GetDeviceInfo(c),
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}

	totalUnread := 0
	chatList := []api_models.ChatList{}
	//暂时去掉群聊
	//for _, v := range groupList.GetGroupList() {
	//	tmp := api_models.ChatList{
	//		UniqId:      fmt.Sprintf("group_chat_%s", v.FansGroupId),
	//		GroupId:     int(v.Id),
	//		AnchorId:    int(v.AnchorId),
	//		Avatar:      v.Avatar,
	//		Name:        v.Name,
	//		UserNum:     int(v.UserNum),
	//		Type:        0,
	//		UnreadNum:   int(v.UnreadNum),
	//		IsOnline:    v.IsOnline,
	//		FansGroupId: v.FansGroupId,
	//	}
	//	chatList = append(chatList, tmp)
	//	totalUnread += tmp.UnreadNum
	//}

	for _, v := range privateChatList.ChatsGroup {
		num := cache2.GetPrivateChatUnread(int(v.AnchorId), user.Id)
		tmp := api_models.ChatList{
			UniqId:    fmt.Sprintf("private_chat_%d", v.AnchorId),
			AnchorId:  int(v.AnchorId),
			Avatar:    v.AnchorAvatar,
			Name:      v.AnchorName,
			UserNum:   0,
			Type:      1,
			UnreadNum: num,
			IsOnline:  v.IsLiveOnline,
			ChatTime:  v.ChatTime,
			Status:    v.Status,
			PrivateChatLatestMsg: api_models.PrivateChatLatestMsg{
				ChatSessionId: v.ChatSessionId,
				LatestMsgTime: v.LatestMsgTime,
				LatestMsg:     v.LatestMsg,
				FromWho:       int(v.FromWho),
			},
		}
		chatList = append(chatList, tmp)
		totalUnread += tmp.UnreadNum
	}

	//暂时去掉主播私聊
	//for _, v := range mgrChats.GetMgrChatList() {
	//	tmp := api_models.ChatList{
	//		UniqId:        fmt.Sprintf("mgr_chat_%d_%d", v.MgrId, v.MgrChatUserId),
	//		Avatar:        v.Avatar,
	//		Name:          v.NickName,
	//		Type:          2,
	//		UnreadNum:     int(v.UnreadNum),
	//		MgrId:         int(v.MgrId),
	//		MgrChatUserId: int(v.MgrChatUserId),
	//		MgrChatId:     fmt.Sprintf("%d_%d", v.MgrId, v.MgrChatUserId),
	//	}
	//	chatList = append(chatList, tmp)
	//	totalUnread += tmp.UnreadNum
	//}

	resp := api_models.GetChatListResp{
		TotalUnread: totalUnread,
		ChatList:    chatList,
	}
	return util.BuildSuccess(c, resp, "")
}

// GetHistory
// @Summary 粉丝群聊天记录
// @Description 粉丝群聊天记录
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.GetFansGroupHistoryRequest true "body"
// @Success 200 {object} protobuf.FansGroupHistoryResponse "result"
// @Router /api/groupChat/getHistory [POST]
func (base *Controller) GetHistory(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := api_models.GetFansGroupHistoryRequest{}
	if err := base.BindAndValid(c, &req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcTencentImClient.GetFansGroupHistory(ctx, &pb.FansGroupHistoryRequest{
		GroupId: req.GroupId,
		UserId:  int32(user.Id),
		Page:    req.Page,
		Limit:   req.Limit,
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	if len(resp.FansGroupHistory) == 0 {
		resp.FansGroupHistory = []*pb.FansGroupHistory{}
	}

	return util.BuildSuccess(c, resp, "")
}

// @Summary 禁言用户-详情
// @Description 禁言用户-详情
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.GetBanInfoReq true "body"
// @Success 200 {object} api_models.GetBanInfoResp "result"
// @Router /api/groupChat/getBanInfo [POST]
func (base *Controller) GetBanInfo(c echo.Context) error {
	req := &api_models.GetBanInfoReq{}
	if err := util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	resp, err := grpc_client.GrpcTencentImClient.GetBanInfo(ctx, &pb.GetBanInfoReq{
		UserId:      uint64(req.BanUserId),
		FansGroupId: req.FansGroupId,
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	res := api_models.GetBanInfoResp{}
	copier.Copy(&res, &resp)
	return util.BuildSuccess(c, res, "")
}

// @Summary 解禁用户
// @Description 解禁用户
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.CancelBanUserReq true "body"
// @Success 200 {object} api_models.Response "result"
// @Router /api/groupChat/cancelBanUser [POST]
func (base *Controller) CancelBanUser(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.CancelBanUserReq{}
	if err := util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}
	ctx, cancel := base.GrpcWithTimeout()
	defer cancel()
	_, err = grpc_client.GrpcTencentImClient.FrontendCancelBanUser(ctx, &pb.FrontendCancelBanUserReq{
		OperateUserId: uint64(user.Id),
		BanUserId:     uint32(req.BanUserId),
		FansGroupId:   req.FansGroupId,
	})
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	if err != nil {
		return util.BuildFail(c, 1, err.Error(), err)
	}
	return util.BuildSuccess(c, nil, "")
}

// @Summary 重置粉丝群未读计数
// @Description 重置粉丝群未读计数
// @Accept  json
// @Produce  json
// @Tags GroupChat
// @Param   sendBody body api_models.ReadReq true "body"
// @Success 200 {object} api_models.Response "result"
// @Router /api/groupChat/read [POST]
func (base *Controller) Read(c echo.Context) error {
	user, err := base.GetUserByCtx(c)
	if err != nil {
		return util.BuildLoginTimeOut(c, err)
	}

	req := &api_models.ReadReq{}
	if err := util.Json2Struct(c.Get("body").(string), req); err != nil {
		return util.BuildFail(c, 1, "", err)
	}

	cache2.ResetGroupMsgUserRead(cast.ToString(user.Id), req.FansGroupId)

	return util.BuildSuccess(c, nil, "")
}
